package org.loofer.ext.component.drawable;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Xfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.graphics.drawable.ShapeDrawable;

public class XfermodeDrawable extends DrawableDecorator {
    private XfermodeState mState;

    static class XfermodeState extends DrawableDecoratorState {
        Xfermode mXfermode;

        XfermodeState(XfermodeState orig, DrawableDecorator owner, Resources res) {
            super(orig, owner, res);
            if (orig != null) {
                this.mXfermode = orig.mXfermode;
            }
        }

        public Drawable newDrawable() {
            return new XfermodeDrawable(this, null);
        }

        public Drawable newDrawable(Resources res) {
            return new XfermodeDrawable(this, res);
        }
    }

    public XfermodeDrawable(Drawable drawable) {
        this(drawable, null);
    }

    public XfermodeDrawable(Drawable drawable, Xfermode xfermode) {
        if (support(drawable)) {
            this.mState = new XfermodeState(null, this, null);
            this.mState.mXfermode = xfermode;
            this.mState.setDrawable(drawable);
            setConstantState(this.mState);
            return;
        }
        throw new RuntimeException("No xfermode support for " + drawable.getClass().getSimpleName());
    }

    public void setXfermode(Xfermode xfermode) {
        if (this.mState.mXfermode != xfermode) {
            this.mState.mXfermode = xfermode;
            invalidateSelf();
        }
    }

    public void draw(Canvas canvas) {
        Paint paint = obtainPaint(this.mState.mDrawable);
        Xfermode xfermode = this.mState.mXfermode;
        if (!(paint == null || paint.getXfermode() == xfermode)) {
            paint.setXfermode(xfermode);
        }
        super.draw(canvas);
    }

    public static Drawable create(Drawable drawable, Xfermode xfermode) {
        if (drawable == null || !support(drawable)) {
            return drawable;
        }
        return new XfermodeDrawable(drawable, xfermode);
    }

    public static boolean support(Drawable drawable) {
        return drawable == null || obtainPaint(drawable) != null;
    }

    private static Paint obtainPaint(Drawable drawable) {
        if (drawable == null || (drawable instanceof XfermodeDrawable)) {
            return null;
        }
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getPaint();
        }
        if (drawable instanceof NinePatchDrawable) {
            return ((NinePatchDrawable) drawable).getPaint();
        }
        if (drawable instanceof ShapeDrawable) {
            return ((ShapeDrawable) drawable).getPaint();
        }
        if (drawable instanceof DrawableDecorator) {
            return obtainPaint(((DrawableDecorator) drawable).getDecor());
        }
        return null;
    }

    private XfermodeDrawable(XfermodeState state, Resources res) {
        this.mState = new XfermodeState(state, this, res);
        setConstantState(this.mState);
    }
}
